package com.fsm.demo.serviceImpl;

import com.alibaba.excel.EasyExcel;
import com.mybatisflex.core.logicdelete.LogicDeleteManager;
import jakarta.servlet.http.HttpServletResponse;
import com.fsm.common.tools.Result.Result;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.fsm.demo.entity.ClientInfo;
import com.fsm.demo.entity.excelbo.ClientInfoBo;
import com.fsm.demo.entity.table.ClientInfoTable;
import com.fsm.demo.mapper.ClientInfoMapper;
import com.fsm.demo.service.ClientInfoService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.apache.commons.lang3.StringUtils;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Date;

/**
 *  客户信息服务层实现。
 *
 * @author 翻山鸣
 * @since
 */
@Service
public class ClientInfoServiceImpl extends ServiceImpl<ClientInfoMapper, ClientInfo> implements ClientInfoService {

    /**
     * 公共整合查询条件
     * @param clientInfo
     * @return
     */
    private static QueryWrapper getSelectQueryWrapper(ClientInfo clientInfo){
        QueryWrapper queryWrapper = new QueryWrapper();
        //判断是否传入姓名
        if(StringUtils.isNotBlank(clientInfo.getName())){
            queryWrapper.where(ClientInfoTable.CLIENT_INFO.NAME.eq(clientInfo.getName()));
        }
        //判断是否传入查询时间
        if(clientInfo.getQueryBeginTime() != null && clientInfo.getQueryEndTime() != null){
            queryWrapper.where(ClientInfoTable.CLIENT_INFO.CREATE_TIME.between(clientInfo.getQueryBeginTime(),clientInfo.getQueryEndTime()));
        }
		queryWrapper.orderBy("create_time desc");
        return queryWrapper;
    }

    /**
     * 添加客户信息
     *
     * @param clientInfo
     * @return
     */
    @Override
    @Transactional
    public Result addClientInfo(ClientInfo clientInfo) throws Exception {
        if(this.getMapper().insert(clientInfo) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.fail("添加客户信息失败");
        }
        return Result.ok();
    }

    /**
    * 逻辑删除客户信息
    *
    * @param clientInfo
    * @return
    */
    @Override
    @Transactional
    public Result logicDeleteClientInfo(ClientInfo clientInfo) throws Exception {
        if(this.getMapper().deleteById(clientInfo.getId()) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.fail("删除客户信息失败");
        }
        return Result.ok();
    }

    /**
     * 删除客户信息
     *
     * @param clientInfo
     * @return
     */
    @Override
	@Transactional
    public Result deleteClientInfo(ClientInfo clientInfo) throws Exception {
        if(LogicDeleteManager.execWithoutLogicDelete(()->
            this.getMapper().deleteById(clientInfo.getId())
        ) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.fail("删除客户信息失败");
        }
        return Result.ok();
    }

    /**
     * 更新客户信息
     *
     * @param clientInfo
     * @return
     */
    @Override
	@Transactional
    public Result updateClientInfo(ClientInfo clientInfo) throws Exception {
        if(this.getMapper().update(clientInfo) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.fail("更新客户信息失败");
        }
        return Result.ok();
    }

    /**
     * 分页查询客户信息
     *
     * @param clientInfo
     * @return
     */
    @Override
    public Result pageClientInfo(ClientInfo clientInfo) throws Exception {
        QueryWrapper queryWrapper = getSelectQueryWrapper(clientInfo);
        Page<ClientInfo> clientInfoPage = this.getMapper().paginateWithRelations(clientInfo.getPage(),clientInfo.getLimit(),queryWrapper);
        return Result.ok(clientInfoPage.getRecords(),clientInfoPage.getTotalRow());
    }

    /**
     * 查询客户信息
     *
     * @param clientInfo
     * @return
     */
    @Override
    public Result getClientInfoList(ClientInfo clientInfo) throws Exception{
        QueryWrapper queryWrapper = getSelectQueryWrapper(clientInfo);
        List<ClientInfo> clientInfoList = this.getMapper().selectListWithRelationsByQuery(queryWrapper);
        return Result.ok(clientInfoList,clientInfoList.size());
    }

    /**
     * 通过ID查询客户信息
     *
     * @param clientInfo
     * @return
     */
    @Override
    public Result getClientInfoById(ClientInfo clientInfo) throws Exception{
        ClientInfo clientInfoOne = this.getMapper().selectOneWithRelationsById(clientInfo.getId());
        return Result.ok(clientInfoOne);
    }

    /**
     * 导出客户信息信息
     *
     * @param
     * @return 分页对象
     */
    @Override
    public Result uploadClientInfoData(ClientInfo clientInfo, HttpServletResponse response) throws Exception {
        //准备需要输出的数据 调用业务层，获得所有需要导出的数据
        QueryWrapper queryWrapper = getSelectQueryWrapper(clientInfo);
        List<ClientInfo> clientInfoList = this.getMapper().selectListWithRelationsByQuery(queryWrapper);
        List<ClientInfoBo> clientInfoBos = new ArrayList<>();
        for (ClientInfo clientInfoOne : clientInfoList){
           ClientInfoBo clientInfoBo = new ClientInfoBo();
           BeanUtils.copyProperties(clientInfoOne,clientInfoBo);
           clientInfoBos.add(clientInfoBo);
        }
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("客户信息表", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=" + fileName + ".xlsx");
        OutputStream outputStream = response.getOutputStream();
        EasyExcel.write(outputStream, ClientInfoBo.class).sheet("模板").doWrite(clientInfoBos);
        return Result.ok();
    }


    /**
    * 冻结客户信息
    *
    * @param clientInfo
    * @return
    */
    @Override
    @Transactional
    public Result freezeClientInfo(ClientInfo clientInfo) throws Exception {
        //重新查询数据
        ClientInfo oldClientInfo = this.getMapper().selectOneById(clientInfo.getId());
        if(oldClientInfo.getFreezeState() != 0){
            return Result.fail("客户信息已冻结");
        }
        oldClientInfo.setFreezeState(0);
        if(this.getMapper().update(oldClientInfo) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.fail("冻结客户信息失败");
        }
        return Result.ok();
    }

    /**
    * 解冻客户信息
    *
    * @param clientInfo
    * @return
    */
    @Override
    @Transactional
    public Result thawClientInfo(ClientInfo clientInfo) throws Exception {
        //重新查询数据
        ClientInfo oldClientInfo = this.getMapper().selectOneById(clientInfo.getId());
        if(oldClientInfo.getFreezeState() != 1){
            return Result.fail("客户信息已解冻");
        }
        oldClientInfo.setFreezeState(1);
        if(this.getMapper().update(oldClientInfo) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.fail("解冻客户信息失败");
        }
        return Result.ok();
    }
    /**
    * 审核通过客户信息
    *
    * @param clientInfo
    * @return
    */
    @Override
    @Transactional
    public Result approvedClientInfo(ClientInfo clientInfo) throws Exception {
        //重新查询数据
        ClientInfo oldClientInfo = this.getMapper().selectOneById(clientInfo.getId());
        if(oldClientInfo.getAuditingState() != 0){
            return Result.fail("客户信息已审核");
        }
        oldClientInfo.setAuditingState(1);
        oldClientInfo.setAuditingTime(new Date());
        if(this.getMapper().update(oldClientInfo) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.fail("审核通过客户信息失败");
        }
        return Result.ok();
    }

    /**
    * 审核驳回客户信息
    *
    * @param clientInfo
    * @return
    */
    @Override
    @Transactional
    public Result reviewClientInfo(ClientInfo clientInfo) throws Exception {
        //重新查询数据
        ClientInfo oldClientInfo = this.getMapper().selectOneById(clientInfo.getId());
        if(oldClientInfo.getAuditingState() != 0){
            return Result.fail("客户信息已审核");
        }
        oldClientInfo.setAuditingState(2);
        oldClientInfo.setAuditingTime(new Date());
        if(this.getMapper().update(oldClientInfo) == 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.fail("审核驳回客户信息失败");
        }
        return Result.ok();
    }

}
